using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.IO.Ports;
using System.Threading;
using System.Diagnostics;
using Bentley.GenerativeComponents;
using Bentley.GenerativeComponents.Features;
using Bentley.GenerativeComponents.Features.Specific;
using Bentley.GenerativeComponents.GeneralPurpose;
using Bentley.GenerativeComponents.GCScript;
using Bentley.GenerativeComponents.GCScript.GCTypes;
using Bentley.GenerativeComponents.GCScript.Namescopes;
using Bentley.GenerativeComponents.MicroStation;
using Bentley.Geometry;

namespace Bentley.GenerativeComponents.Features
{    
    
    public class UpdateServo: Feature
    {
        private string _portName = "COM16";
        private int _baudRate = 9600;
        private SerialPort _serialPort;
        private static DebugForm _debFrm = new DebugForm();

        public UpdateServo()
        {                        
        }

        public UpdateServo(Feature parentFeature)
            : base(parentFeature)
        {
        }
        
        [Update]
        public bool UpdateServoByAVariable
            (FeatureUpdateContext updateContext,
            string PortName,           //e.g. COM16
            double servoNo,             //e.g. 1 - starts from 1
            double servoAngle,         //0-180
            CoordinateSystem cs)
        {
            if (servoAngle >= 0 && servoAngle <= 180)
            {
                //if (!_debFrm.Visible)
                //{
                //    _debFrm.Show();
                //}

                this._portName = PortName;
                //string message;
                //char[] msg = new char[2];                
                //msg[0] = (char) servoAngle;
                //msg[1] = servoNo.ToCharArray() [0];
                string message = servoNo + "," + servoAngle + "!";
                
                //byte[] msg = new byte[message.Length];
                //message = System.Text.ASCIIEncoding.ASCII.GetString(msg);
                char[] msg = new char[message.Length];
                msg = message.ToCharArray();
                                
                _serialPort = new SerialPort(_portName, _baudRate, Parity.None, 8, StopBits.One);
                //_serialPort.DataReceived += OnSerialData;
                //_serialPort.ErrorReceived += OnSerialError;
                _serialPort.DtrEnable = true;
                if (!_serialPort.IsOpen)
                    _serialPort.Open();
                Thread.Sleep(3000);
                
                _serialPort.Write(msg, 0, msg.Length);
                Thread.Sleep(2000);
                _serialPort.Close();
                Thread.Sleep(2000);
                
                Debug.WriteLine("servo angle updated to \"{0}\" " + servoAngle);
                Debug.Flush();

                return true;
            }
            else
                return false;
        }

        private void OnSerialData(Object sender, SerialDataReceivedEventArgs args)
        {
            SerialPort port = (SerialPort)sender;
            if (args.EventType == SerialData.Chars)
            {
                string data = port.ReadExisting();
                //this.AddData(data.ToCharArray());
                _debFrm.AppendText(data);
                port.Close();

            }
            else
            {
                port.Close();
            }
        }

        //public void OnSerialError(Object sender, SerialErrorReceivedEventArgs e)
        //{
        //    Console.WriteLine("Received error on socket");
        //    port.Close();
        //    SendError();
        //}

    }
}
